import {
  Body,
  Controller,
  Inject,
  Post,
  SetMetadata,
  UnauthorizedException,
  ValidationPipe,
} from '@nestjs/common';
import { UserService } from './user.service';
import { RegisterUserDto } from './dto/register-user.dto';
import { RedisService } from 'src/redis/redis.service';
import { EmailService } from 'src/email/email.service';
import { LoginUserDto } from './dto/login-user.dto';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { User } from './entities/user.entity';
import { LoginUserVO } from './vo/login-user.vo';
import { UserInfo } from './vo/login-user.vo';
import { tokenConfig } from './config/useToken';
import { RequireLogin, UserInfoDe } from 'src/custom.decorator';
import { UpdatePasswordUserDto } from './dto/update-password-user-dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UserListDto } from './dto/user-list.dto';
import { IsNotEmpty } from 'class-validator';
class Email {
  @IsNotEmpty({
    message: '邮箱不能为空',
  })
  to: string;
}
@Controller('/user')
export class UserController {
  constructor(private readonly userService: UserService) {}
  @Inject()
  private redisService: RedisService;
  @Inject()
  private emailService: EmailService;
  @Inject()
  private jwtService: JwtService;
  @Inject()
  private configService: ConfigService;
  @Post('register')
  register(@Body() registerUser: RegisterUserDto) {
    return this.userService.register(registerUser);
  }
  @Post('register-captcha')
  async captcha(@Body() address: Email) {
    const code = Math.random().toString().slice(2, 8);
    await this.redisService.set(`captcha_${address.to}`, code, 60);
    await this.emailService.sendMail({
      to: address.to,
      subject: '注册验证码',
      html: `<p>你的注册验证码是${code}</p>`,
    });
    return '发送成功';
  }
  @Post('init-data')
  async initData() {
    await this.userService.initData();
    return '初始化成功';
  }

  @Post('login')
  async userLogin(@Body() loginUser: LoginUserDto) {
    const { isAdmin = false } = loginUser;
    const vo = await this.userService.userLogin(loginUser, isAdmin);
    vo.accessToken = this.jwtService.sign(tokenConfig(vo.userInfo), {
      expiresIn:
        this.configService.get('jwt_access_token_expires_time') || '1m',
    });
    vo.refreshToken = this.jwtService.sign(
      {
        userId: vo.userInfo.id,
      },
      {
        expiresIn:
          this.configService.get('jwt_refresh_token_expires_time') || '7d',
      },
    );
    return vo;
  }

  @Post('refresh')
  async refresh(@Body() body: { refreshToken: string }) {
    const { refreshToken } = body;
    try {
      const data = this.jwtService.verify(refreshToken);
      const user = (await this.userService.findUserById(
        data.userId,
        false,
      )) as unknown as UserInfo;
      const access_token = this.jwtService.sign(tokenConfig(user), {
        expiresIn:
          this.configService.get('jwt_access_token_expires_time') || '1m',
      });
      const refresh_token = this.jwtService.sign(
        {
          userId: user.id,
        },
        {
          expiresIn:
            this.configService.get('jwt_refresh_token_expres_time') || '7d',
        },
      );

      return {
        access_token,
        refresh_token,
      };
    } catch (err) {
      throw new UnauthorizedException('token 已过期，请重新登录');
    }
  }
  @Post('admin/refresh')
  async adminRefresh(@Body() body: { refreshToken: string }) {
    const { refreshToken } = body;
    try {
      const data = this.jwtService.verify(refreshToken);

      const user = (await this.userService.findUserById(
        data.userId,
        true,
      )) as UserInfo;

      const access_token = this.jwtService.sign(tokenConfig(user), {
        expiresIn:
          this.configService.get('jwt_access_token_expires_time') || '30m',
      });

      const refresh_token = this.jwtService.sign(
        {
          userId: user.id,
        },
        {
          expiresIn:
            this.configService.get('jwt_refresh_token_expres_time') || '7d',
        },
      );

      return {
        access_token,
        refresh_token,
      };
    } catch (e) {
      throw new UnauthorizedException('token 已失效，请重新登录');
    }
  }
  @Post('info')
  @RequireLogin()
  async info(@UserInfoDe('userId') userId: number) {
    return this.userService.findUserDetailById(userId);
  }

  @Post(['update_password', 'admin/update_password'])
  async updatePassword(@Body() passwordDto: UpdatePasswordUserDto) {
    const { email, captcha } = passwordDto;
    const code = await this.redisService.get(`captcha_${email}`);
    if (!code) {
      throw new UnauthorizedException('验证码已过期');
    }
    if (code !== captcha) {
      throw new UnauthorizedException('验证码错误');
    }
    return await this.userService.updatePassword(passwordDto);
  }
  @Post(['update', 'admin/update'])
  @RequireLogin()
  async updateUser(
    @UserInfoDe('userId') userId: number,
    @Body() updateUserDto: UpdateUserDto,
  ) {
    return await this.userService.updateUser(userId, updateUserDto);
  }
  @Post('list')
  @RequireLogin()
  async userList(@Body() userListDto: UserListDto) {
    return await this.userService.userList(userListDto);
  }
}
